/***************String扩展****************/
/**
 * 去掉字符串两边空格
 * @returns {string}
 */
String.prototype.trim = function () {
    return this.replace(/(^\s*)|(\s*$)/g, "");
};
/**
 *  去掉字符串左边空格
 * @returns {string}
 */
String.prototype.trimLeft = function () {
    return this.replace(/^\s*/, "");
};
/**
 *  去掉字符串右边空格
 * @returns {string}
 */
String.prototype.trimRight = function () {
    return this.replace(/\s*$/, "");
};
/**
 *验证字符串是否以str开始
 * @param str
 * @returns {boolean}
 */
String.prototype.startWith = function (str) {
    return isEmpty(str) ? false : this.substring(0, str.length) == str;
};
/**
 *验证字符串是否以str结束
 * @param str
 * @returns {boolean}
 */
String.prototype.endWith = function (str) {
    return isEmpty(str) ? false : this.substring(this.length - str.length) == str;
};
/**
 * 替换字符串
 *  @param {String...}
 *            str | {Array} arr 可以是多个字符串或者是字符串数组
 * @returns {String}
 */
String.prototype.format = function () {
    var args = isArray(arguments[0]) ? arguments[0] : arguments;
    var result = this;
    for (var i = 0, len = args.length; i < len; i++) {
        result = result.replace("{" + i + "}", args[i]);
    }
    return result;
};
/**
 * 替换所有字符串
 * @param regexp
 * @param replacement
 * @returns {string}
 */
String.prototype.replaceAll = function (regexp, replacement) {
    return this.replace(new RegExp(regexp, "g"), replacement);
};
/**
 * 获取字符串真实长度 一个汉字算2位
 * @returns {number}
 */
String.prototype.realLength = function () {
    return this.replace(/[^\x00-\xff]/g, "**").length;
};

/**
 *  判断非空
 * @param obj
 * @returns {boolean}
 */
function isEmpty(obj) {
    if (obj === undefined || obj === null || (obj + "").trim() === 'null' || (obj + "").trim() === '') {
        return true;
    } else {
        return false;
    }
}
/**
 *  判断非空
 * @param obj
 * @returns {boolean}
 */
function isNotEmpty(obj) {
    return isEmpty(obj) ? false : true;
}

/**
 * 追加字符串
 * @param str
 * @returns {string}
 */
String.prototype.append = function (str) {
    return this.concat(str);
};
/**
 * 删除指定索引位置的字符，索引无效将不删除任何字符
 * @param index
 * @returns {string}
 */
String.prototype.deleteCharAt = function (index) {
    if (index < 0 || index >= this.length) {
        return this.valueOf();
    }
    else if (index == 0) {
        return this.substring(1, this.length);
    }
    else if (index == this.length - 1) {
        return this.substring(0, this.length - 1);
    }
    else {
        return this.substring(0, index) + this.substring(index + 1);
    }
};
/**
 * 删除指定索引区间的字符串
 * @param start
 * @param end
 * @returns {string}
 */
String.prototype.deleteString = function (start, end) {
    if (start == end) {
        return this.deleteCharAt(start);
    }
    else {
        if (start > end) {
            var temp = start;
            start = end;
            end = temp;
        }
        if (start < 0) {
            start = 0;
        }
        if (end > this.length - 1) {
            end = this.length - 1;
        }
        return this.substring(0, start) + this.substring(end +1 , this.length);
    }
};
/**
 *比较两个字符串是否相等，也可以直接用 == 进行比较
 * @param str
 * @returns {boolean}
 */
String.prototype.equal = function (str) {
    if (this.length != str.length) {
        return false;
    }
    else {
        for (var i = 0; i < this.length; i++) {
            if (this.charAt(i) != str.charAt(i)) {
                return false;
            }
        }
        return true;
    }
};
/**
 * 比较两个字符串是否相等，不区分大小写
 * @param str
 * @returns {boolean}
 */
String.prototype.equalIgnoreCase = function (str) {
    var temp1 = this.toLowerCase();
    var temp2 = str.toLowerCase();
    return temp1.equal(temp2);
};
/**
 * 将指定的字符串插入到指定的位置后面，索引无效将直接追加到字符串的末尾
 * @param ofset
 * @param subStr
 * @returns {string}
 */
String.prototype.insert = function (ofset, subStr) {
    if (ofset < 0 || ofset >= this.length - 1) {
        return this.append(subStr);
    }
    return this.substring(0, ofset + 1) + subStr + this.substring(ofset + 1);
};
/**
 * 获取N个相同的字符串
  * @param num
 * @returns {string}
 */
String.prototype.repeat = function(num) {
    var tmpArr = [];
    for ( var i = 0; i < num; i++){
        tmpArr.push(this);
    }
    return tmpArr.join("");
};
/**
 * 将字符串反序排列
 * @returns {string}
 */
String.prototype.reverse = function() {
    return this.split("").reverse().join("");
};
/**
 * 将指定的位置的字符设置为另外指定的字符或字符串.索引无效将直接返回不做任何处理
 * @param index
 * @param subStr
 * @returns {string}
 */
String.prototype.setCharAt = function (index, subStr) {
    if (index < 0 || index > this.length - 1) {
        return this.valueOf();
    }
    return this.substring(0, index) + subStr + this.substring(index+1);
};
/**
 * 计算长度，每个汉字占两个长度，英文字符每个占一个长度
 * @returns {number}
 */
String.prototype.charLength = function () {
    var temp = 0;
    for (var i = 0; i < this.length; i++) {
        if (this.charCodeAt(i) > 255) {
            temp += 2;
        }
        else {
            temp += 1;
        }
    }
    return temp;
};
/**
 * 得到字节长度
 * @returns {number}
 */
String.prototype.getRealLength = function () {
    return this.replace(/[^x00-xff]/g, "--").length;
};
/**
 * 从左截取指定长度的字串
 * @param n
 * @returns {string}
 */
String.prototype.left = function (n) {
    return this.slice(0, n);
};
/**
 * 从右截取指定长度的字串
 * @param n
 * @returns {string}
 */
String.prototype.right = function (n) {
    return this.slice(this.length - n);
};
/**
 * 统计指定字符出现的次数
 * @param ch
 * @returns {number}
 * @constructor
 */
String.prototype.Occurs = function(ch) {
//  var re = eval("/[^"+ch+"]/g");
//  return this.replace(re, "").length;
    return this.split(ch).length-1;
};
/**
 * 检查是否由正整数
 * @returns {boolean}
 */
String.prototype.isDigit = function() {
    var s = this.trim();
    return (s.replace(/\d/g, "").length == 0);
};
/**
 * 检查是否为数字
 * @returns {boolean}
 */
String.prototype.isNumber = function() {
    var s = this.Trim();
    return (s.search(/^[+-]?[0-9.]*$/) >= 0);
};
/**
 * 合并多个空白为一个空白
 * @returns {string}
 */
String.prototype.resetBlank = function() {
    return this.replace(/s+/g, " ");
};
/**
 * 检查是否由数字字母和下划线组成
 * @returns {boolean}
 */
String.prototype.isAlpha = function() {
    return (this.replace(/\w/g, "").length == 0);
};
/**
 * 检查是否包含汉字
 * @returns {boolean}
 */
String.prototype.isInChinese = function() {
    return (this.length != this.replace(/[^\x00-\xff]/g,"**").length);
};
/**
 * 获取字符数组
 * @returns {Array}
 */
String.prototype.toCharArray = function() {
    return this.split("");
};
/***************Array扩展*****************/
var slice = Array.prototype.slice;
/**
 *
 * @param item
 * @returns {number}
 */
Array.prototype.indexOf = function (item) {
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i] == item) {
            return i;
        }
    }
    return -1;
};

Array.prototype.size = function () {
    return this.length;
};
/**
 * 清空数组
 * @returns {Array}
 */
Array.prototype.clear = function () {
    this.length = 0;
    return this;
};
/**
 * 克隆一个数组
 * @returns {Array.<T>}
 */
Array.prototype.clone = function () {
    return slice.call(this, 0);
};
/**
 * 按条件过渡数组
 * @param fun
 * @returns {Array}
 */
Array.prototype.filter = function (fun) {
    var values = [];
    for (var i = 0, len = this.length; i < len; i++) {
        if (fun.call(null, this[i], i,this)) {
            values.push(this[i]);
        }
    }
    return values;
};
Array.prototype.compact=function(){
    var func = function(item,index,array){
        if(isEmpty(item)){
            return false;
        }
        return true;
    };
    return this.filter(func);
}
/**
 * 如果数组中的每个元素都能通过给定的函数的测试，则返回true，反之false。
 * 换言之给定的函数也一定要返回true与false
 * @param fn
 * @param thisObj
 * @returns {boolean}
 */
Array.prototype.every = function(fn) {
    for ( var i=0, j=this.length; i < j; ++i ) {
        if ( !fn.call(null,this[i], i, this) ) {
            return false;
        }
    }
    return true;
};
/**
 * 类似every函数，但只要有一个通过给定函数的测试就返回true
 * @param fn
 * @param thisObj
 * @returns {boolean}
 */
Array.prototype.some = function(fn) {

    for ( var i=0, j=this.length; i < j; ++i ) {
        if ( fn.call(null, this[i], i, this) ) {
            return true;
        }
    }
    return false;
};
/**
 * 扩展Array类,实现一个each函数，
 * @param fun
 */
Array.prototype.each=function( fun ){
    for( var i=0,n=this.length;i<n;i++){
        fun.call(null,this[i], i, this);
    }
};
/**
 * 让数组中的每一个元素调用给定的函数，然后把得到的结果放到新数组中返回
 * @param fn
 * @param thisObj
 * @returns {Array}
 */
Array.prototype.map = function(fn) {
    var a = [];
    for ( var i=0, j=this.length; i < j; ++i ) {
        a.push(fn.call(null, this[i], i, this));
    }
    return a;
};
/**
 *
 * @param item
 * @returns {*}
 */
Array.prototype.remove = function (item) {
    var itemIndex = this.indexOf(item);
    if (itemIndex >= 0) {
        this.splice(itemIndex, 1);
        return itemIndex;
    }
    return -1;
};
/**
 *
 * @param arr
 */
Array.prototype.removeAll = function (arr) {
    for (var i = 0, len = arr.length; i < len; i++) {
        this.remove(arr[i]);
    }
};
/**
 *
 * @param item
 */
Array.prototype.add = function (item) {
    this.push(item);
};
/**
 *
 * @param arr
 */
Array.prototype.addAll = function (arr) {
    for (var i = 0;i < arr.length; i++) {
        this.add(arr[i]);
    }
};
/**
 * 删除数组中指定索引的数据
 * @param index
 * @returns {*}
 */
Array.prototype.deleteAt = function (index) {
    if (index < 0) {
        return this;
    }
    return this.slice(0, index).concat(this.slice(index + 1, this.length));
};
/**
 * 数组洗牌
 * @returns {Array}
 */
Array.prototype.random = function () {
    var tempArr = [], me = this, t;
    while (me.length > 0) {
        t = Math.floor(Math.random() * me.length);
        tempArr[tempArr.length] = me[t];
        me = me.deleteAt(t);
    }
    return tempArr;
};
/**
 * 数字数组排序
 * @param i
 * @returns {Array.<T>}
 */
Array.prototype.sortNum = function (i) {
    if (!i) {
        i = 0;
    }
    if (i == 1) {
        return this.sort(function (a, b) {
            return b - a;
        });
    }
    return this.sort(function (a, b) {
        return a - b;
    });
};
/**
 * 获取数字数组中的最大项
 * @returns {T}
 */
Array.prototype.getMax = function () {
    return this.sortNum(1)[0];
};
/**
 * 获取数字数组中的最小项
 * @returns {T}
 */
Array.prototype.getMin = function () {
    return this.sortNum(0)[0];
};
/**
 * 去除数组中的重复项
 * @returns {Array}
 */
Array.prototype.arrUnique = function () {
    var reset = [], done = {};
    for (var i = 0; i < this.length; i++) {
        var temp = this[i];
        if (!done[temp]) {
            done[temp] = true;
            reset.push(temp);
        }
    }
    return reset;
};
/**
 * 判断是否存在,通过元素的id
 * @param elementId
 * @returns {*}
 */
Array.prototype.getElementById=function(elementId){
    for(var i=0;i<this.length;i++){
        if(this[i].id== elementId){
            return this[i];
        }
    }
};
/**
 * 确定某个元素是否在数组中
 * @param element
 * @returns {boolean}
 */
Array.prototype.contains=function(element){
    for(var i=0;i<this.length;i++){
        if(this[i]== element){
            return true;
        }
    }
    return false;
};
/**
 * 判断是否存在,通过元素的id
 * @param elementId
 * @returns {boolean}
 */
Array.prototype.containsById=function(elementId){
    for(var i=0;i<this.length;i++){
        if(this[i].id== elementId){
            return true;
        }
    }
    return false;
};
/**
 * 删除Array的元素,通过元素的Id
 * @param elementId
 */
Array.prototype.removeById=function(elementId){
    for(var i=0;i<this.length;i++){
        if(this[i].id == elementId){
            this.splice(i,1);
        }
    }
};
/**
 * 将字符串解析为日期对象
 *
 * @param {String}
 *            日期字符串
 * @param {String}
 *            日期格式
 * @returns
 * @throws
 */
var parseDate=function() {
    var timeStr, format;
    if (arguments.length === 0) {
        return new Date();
    } else if (arguments.length === 1) {
        timeStr = arguments[0];
        format = 'yyyy-MM-dd HH:mm:ss';
    } else if (arguments.length === 2) {
        timeStr = arguments[0];
        format = arguments[1];
    }

    if (timeStr.length != format.length) {
        alert('参数错误');
        return;
    }
    var yearExpr = /(yyyy)+|(YYYY)+|(yy)+|(YY)+/g;
    var monthExpr = /(MM)+|(M)+/g;
    var dateExpr = /(dd)+|(DD)+|(d)+|(D)+/g;
    var hourExpr = /(HH)+|(H)+/g;
    var miniteExpr = /(mm)+|(m)+/g;
    var secondExpr = /(ss)+|(SS)|(s)+|(S)+/g;

    var getStr = function (expr) {

        var arr = expr.exec(format);
        if (!arr || arr.length === 0){
            return;
        }
        var p = arr[0];
        var start = format.indexOf(p);
        return timeStr.substr(start, p.length);
    };

    var ret = new Date();
    var year = getStr(yearExpr);
    if (year) {
        ret.setYear(parseInt(year));
    } else {
        ret.setYear(1971);
    }
    var month = getStr(monthExpr);
    if (month) {
        ret.setMonth(parseInt(month) - 1);
    } else {
        ret.setMonth(0);
    }
    var date = getStr(dateExpr);
    if (date) {
        ret.setDate(parseInt(date));
    } else {
        ret.setDate(1);
    }
    var hour = getStr(hourExpr);
    if (hour) {
        ret.setHours(parseInt(hour));
    } else {
        ret.setHours(0);
    }
    var minite = getStr(miniteExpr);
    if (minite) {
        ret.setMinutes(parseInt(minite));
    } else {
        ret.setMinutes(0);
    }
    var second = getStr(secondExpr);
    if (second) {
        ret.setSeconds(parseInt(second));
    } else {
        ret.setSeconds(0);
    }

    return ret;
};
/**
 * 将日期格式化为字符串
 *
 * @param {Date}
 *            日期
 * @param {String}
 *            日期格式
 * @returns
 * @throws
 */
var formatDate=function() {
    var time, format;
    if (arguments.length === 0) {
        time = new Date();
        format = 'yyyy-MM-dd HH:mm:ss';
    } else if (arguments.length === 1) {
        time = arguments[0];
        format = 'yyyy-MM-dd HH:mm:ss';
    } else if (arguments.length === 2) {
        time = arguments[0];
        format = arguments[1];
    }
    var dateStr = format;
    var yearExpr = /(yyyy)+|(YYYY)+|(yy)+|(YY)+/g;
    var monthExpr = /(MM)+|(M)+/g;
    var dateExpr = /(dd)+|(DD)+|(d)+|(D)+/g;
    var hourExpr = /(HH)+|(H)+/g;
    var miniteExpr = /(mm)+|(m)+/g;
    var secondExpr = /(ss)+|(SS)|(s)+|(S)+/g;

    var repStr = function (expr) {
        var arr = expr.exec(format);
        if (!arr || arr.length === 0){
            return;
        }
        var p = arr[0];
        var twobit = function (s) {
            s = s + '';
            return s.length < 2 ? "0" + s : s;
        };
        if (p && (p == 'yyyy' || p == 'YYYY')) {
            dateStr = dateStr.replace(p, time.getFullYear());
        } else if (p && (p == 'yy' || p == 'YY')) {
            var yearStr = time.getYear() + '';
            dateStr = dateStr.replace(p, yearStr.substr(2));
        } else if (p && p == 'MM') {
            dateStr = dateStr.replace(p, twobit(time.getMonth() + 1));
        } else if (p && p == 'M') {
            dateStr = dateStr.replace(p, time.getMonth() + 1);
        } else if (p && (p == 'DD' || p == 'dd')) {
            dateStr = dateStr.replace(p, twobit(time.getDate()));
        } else if (p && (p == 'D' || p == 'd')) {
            dateStr = dateStr.replace(p, time.getDate());
        } else if (p && p == 'HH') {
            dateStr = dateStr.replace(p, twobit(time.getHours()));
        } else if (p && p == 'H') {
            dateStr = dateStr.replace(p, time.getHours());
        } else if (p && p == 'mm') {
            dateStr = dateStr.replace(p, twobit(time.getMinutes()));
        } else if (p && p == 'm') {
            dateStr = dateStr.replace(p, time.getMinutes());
        } else if (p && (p == 'SS' || p == 'ss')) {
            dateStr = dateStr.replace(p, twobit(time.getSeconds()));
        } else if (p && (p == 'S' || p == 's')) {
            dateStr = dateStr.replace(p, time.getSeconds());
        } else {
            return null;
        }
    };

    repStr(yearExpr);
    repStr(monthExpr);
    repStr(dateExpr);
    repStr(hourExpr);
    repStr(miniteExpr);
    repStr(secondExpr);

    return dateStr;
};

/**
 * 回到当前时刻
 * @returns {Date}
 */
Date.prototype.toNow = function() {
    this.setTime(Date.now());
    return this;
};
/**
 * 回到午夜零点
 * @returns {Date}
 */
Date.prototype.toMidnight = function() {
    this.setHours(0);
    this.setMinutes(0);
    this.setSeconds(0);
    return this;
};
Date.prototype.toEndNight = function() {
    this.setHours(23);
    this.setMinutes(59);
    this.setSeconds(59);
    return this;
};
/**
 * 获取若干秒前
 * @param secs
 * @returns {Date}
 */
Date.prototype.secsAgo = function(secs) {
    secs = secs ? secs - 0 : 0;
    return new Date(this.getTime() - secs * 1000);
};
/**
 * 获取几天前
 * @param days
 * @returns {Date}
 */
Date.prototype.daysAgo = function(days) {
    days = days ? days - 0 : 1;
    return this.secsAgo(days * 86400).toMidnight();
};

/**
 * 获取月初第一天
 * @param offset
 * @returns {Date}
 */
Date.prototype.monthBegin = function(offset) {
    offset = offset ? offset - 0 : 0;
    var days = this.getDate() - 1 - offset;
    return this.daysAgo(days);
};

/**
 * 今年第多少天
 * @returns {number}
 */
Date.prototype.getDaysOfYear = function() {
    var first_day = new Date(this.getFullYear(), 0, 1);
    var micro_secs = this.getTime() - first_day.getTime();
    return parseInt(micro_secs / 8.64E7) + 1;
};

/**
 * 今年第多少周
 * @param start
 * @returns {number}
 */
Date.prototype.getWeeksOfYear = function(start) {
    var offset = this.getDaysOfYear() - 1;
    var remain = offset % 7;
    if (remain > 0) {
        var first_day = new Date(this.getFullYear(), 0, 1);
        if (start) { //周一作为一周开始
            offset += (first_day.getDay() + 6) % 7;
        } else { //周日作为一周开始
            offset += first_day.getDay();
        }
    }
    return parseInt(offset / 7);
};
/**
 * 返回下个月的第一天的Date对象
 * @returns {Date}
 */
Date.prototype.getStartOfNextMonth = function(){
    var newDate = new Date(this);
    newDate.setDate(15); //确保月数不会进位
    newDate.setMonth(this.getMonth()+1);
    newDate.setDate(1);
    newDate.toMidnight();
    return newDate;
};

/**
 * 返回下个月的最后一天的Date对象
 * @returns {Date}
 */
Date.prototype.getEndOfNextMonth = function(){
    var newDate = new Date(this);
    newDate.setDate(15); //确保月数不会进位
    newDate.setMonth(this.getMonth() + 2); //加两个月
    newDate.setDate(0); //再退回上个月的最后一天
    newDate.toEndNight();
    return newDate;
};
/**
 * 返回一个加上若干个月的新Date
 * 注1：Date(2-28).plusMonth(1)=Date(3-28)。如果需要变成3-31，需要另外的函数来处理。
 * 注2：Date(1-31).plusMonth(1)=Date(2-28)或Date(2-29)
 * @param num
 * @returns {Date}
 */
Date.prototype.plusMonths = function(num) {
    var newDate = new Date(this);
    newDate.setMonth(this.getMonth() + num); //setMonth()会自动除以12
    //注意：此时，月数可能会自动进位，比如：1-31加上num=1的情况，会变成3-3（非闰年）或3-2（闰年），即2-31自动转换为下个月的某一天。

    var currentMonth = this.getMonth() + this.getFullYear() * 12; //获得月的绝对值
    var diff = (newDate.getMonth() + newDate.getFullYear() * 12) - currentMonth; //计算新旧两个月绝对值的差

    if (diff != num) { //如果月绝对值的差和加上的月数不一样，说明月进位了，此时需要退一个月
        //setDate(0)表示变成上个月的最后一天
        newDate.setDate(0);
    }

    return newDate;
};
/**
 * 返回一个减去days天的新Date
 * @param days
 * @returns {Date}
 */
Date.prototype.minusDays = function(days) {
    return new Date(this.getTime() - days*60*60*24*1000);
};
/**
 * 返回一个加上days天的新Date
 * @param days
 * @returns {Date}
 */
Date.prototype.plusDays = function(days) {
    return new Date(this.getTime() + days*60*60*24*1000);
};
/***************原生对象工类方法****************/
var class2type = {}, toString = Object.prototype.toString;
(function () {
    var typeArr = "Boolean,Number,String,Function,Array,Date,RegExp,Object".split(",");
    for (var i = 0; i < typeArr.length; i++) {
        var name = typeArr[i];
        class2type["[object " + name + "]"] = name.toLowerCase();
    }
})();
/**
 * 返回对象类型
 * @param obj
 * @returns {string}
 */
function type (obj) {
    return obj === null ? String(obj) : class2type[toString.call(obj)] || "object";
}
/**
 * 判断对象是否布尔类型
 * @param obj
 * @returns {boolean}
 */
function isBoolean(obj) {
    return isEmpty(obj) ? false : type(obj) === 'boolean';
}
/**
 * 判断对象是否数值类型
 * @param obj
 * @returns {boolean}
 */
function isNumber(obj) {
    return isEmpty(obj) ? false : type(obj) === 'number';
}
/**
 * 判断对象是否字符类型
 * @param obj
 * @returns {boolean}
 */
function isString(obj) {
    return isEmpty(obj) ? false : type(obj) === 'string';
}
/**
 * 判断对象是否函数类型
 * @param obj
 * @returns {boolean}
 */
function isFunction(obj) {
    return isEmpty(obj) ? false : type(obj) === 'function';
}
/**
 * 判断对象是否数组类型
 * @param obj
 * @returns {boolean}
 */
function isArray(obj) {
    return isEmpty(obj) ? false : type(obj) === 'array';
}
/**
 * 判断对象是否日期型
 * @param obj
 * @returns {boolean}
 */
function isDate(obj) {
    return isEmpty(obj) ? false : type(obj) === 'date';
}
/**
 * 判断对象是否正则表达式类型
 * @param obj
 * @returns {boolean}
 */
function isRegExp(obj) {
    return isEmpty(obj) ? false : type(obj) === 'regexp';
}
/**
 * 判断对象是对象类型
 * @param obj
 * @returns {boolean}
 */
function isObject(obj) {
    return isEmpty(obj) ? false : type(obj) === 'object';
}
 /***************其它工具方法*****************/

/**
 * 将对象序列化成字符串
 * @param obj
 * @returns {string}
 */
function serialize(obj) {
    var str = '';
    if (isEmpty(obj)) {
        return str;
    }
    for (var key in obj) {
        var val = obj[key];

        if (!isArray(val)) {
            str += '&' + key + '=' + val;
        } else {
            for (var i = 0, len = val.length; i < len; i++) {
                str += '&' + key + '=' + val[i];
            }
        }
    }
    return str.substring(1);
}
/**
 * 将字符串反序列化成对象
 * @param obj
 * @returns {string}
 */
function unSerialize(str) {
    var result = {};
    if (isEmpty(str)) {
        return result;
    }
    var params = str.split("&");

    if (isEmpty(params) || params.length === 0) {
        return result;
    }

    for (var i = 0, len = params.length; i < len; i++) {
        var param = params[i];
        var arr = param.split("=");

        var key = arr[0];
        var val = arr[1];

        if (isEmpty(key) || isEmpty(val)) {
            continue;
        }
        var old = result[key];
        if (isEmpty(old)) {
            result[key] = val;
            continue;
        }

        if (!isArray(old)) {
            result[key] = [old, val];
            continue;
        } else {
            old.push(val);
            continue;
        }
    }
    return result;
}
/**
 * 复制文本到粘贴板
 */
function clipboardData(msg) {
    if ($$.browser.isIE) {
        window.clipboardData.clearData();
        window.clipboardData.setData("Text", msg);
        alert("已经成功复制到剪帖板上！");
    } else if (isFirefox) {
        alert("浏览器不支持复制文本到剪帖板");
    }
}
function forbidRight() {
    /*
     * $(document).bind("contextmenu",function(e){ return false; });
     */
    document.oncontextmenu = function () {
        event.returnValue = false;
    };
}
function getParameter(key, loc) {
    var arr = [];
    loc = loc || 0;
    var patt = new RegExp(name + '=([^&]*)', "g");
    var str = location.search.substring(1);

    while ((result = patt.exec(str)) !== null) {
        arr.push(result[1]);
    }

    if (arr.length === 0) {
        return '';
    }
    if (isNotEmpty(loc)) {
        return arr[loc];
    }
    return arr.join(",");
}
function uuid() {
    var b = [], c = "0123456789ABCDEF".split("");
    for (var a = 0; a < 36; a++) {
        b[a] = Math.floor(Math.random() * 16);
    }
    b[14] = 4;
    b[19] = (b[19] & 3) | 8;

    for (var i = 0; i < 36; i++) {
        b[i] = c[b[i]];
    }
    b[8] = b[13] = b[18] = b[23] = "-";
    return b.join("");
}
 function guid(){
     var str = uuid();
     str = str.replaceAll("-","");
     return str;
 }
function logger(msg){
    var d = new Date();
    var time = formatDate(d);
    var info = time + " : " +d.getMilliseconds() + "  " + msg;

    console.info(info);
}

function Map(obj) {
    this.keys = [];
    this.data = {};

    this.containByKey=function(key){
        if(this.keys.indexOf(key) != -1){
            return true;
        }
        return false;
    };
    this.put = function(key, value) {
        if(isEmpty(key)) {
            return;
        }
        if(!this.containByKey(key)){
            this.keys.push(key);
        }
        this.data[key] = value;
    };
    this.get = function(key) {
        if(this.containByKey(key)){
            return this.data[key];
        }
        return null;
    };
    this.remove = function(key) {
        if(this.containByKey(key)){
            this.keys.remove(key);
            this.data[key] = null;
        }
    };

    this.each = function(fn){
        if(typeof fn != 'function'){
            return;
        }
        var len = this.keys.length;
        for(var i=0;i<len;i++){
            var k = this.keys[i];
            fn(k,this.data[k],i);
        }
    };
    this.values = function(){
        var values = {};

        var len = this.keys.length;
        for(var i=0;i<len;i++){
            var key = this.keys[i];
            var value=this.data[key];
            values[key]=value;
        }
        return values;
    } ;
    this.isEmpty = function() {
        return this.keys.length == 0;
    };

    this.size = function(){
        return this.keys.length;
    };

    this.toString = function(){
        return this.toJSONString();
    };
    this.toJSONString = function(){
        return JSON.stringify(this.values());
    };


    if(obj != null){
        for(var key in obj){
            var value = obj[key];
            this.put(key,value);
        }
    }
}